package com.koron;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;

import com.koron.tool.Constant;
import com.koron.tool.MainFrame;
import org.eclipse.jdt.core.dom.*;

/**
 * Created by zhenbiao on 2016/12/5.
 */
public class JavaSourceParserUtil {

    private static ASTParser astParser = ASTParser.newParser(AST.JLS8);


    public static Map<String,List<String>> getNotAutoCode(String filePath){
        Map<String,List<String>>retMap = new HashMap<>();



        List<String>importStrings = new ArrayList<String>();
        List<String>fieldStrings = new ArrayList<String>();
        List<String>methodStrings = new ArrayList<String>();
        retMap.put("import",importStrings);
        retMap.put("field",fieldStrings);
        retMap.put("method",methodStrings);

        //根据系统参数判断是否需要处理代码保留
        if(!"Y".equals(MainFrame.config.get(Constant.CODE_SAVE_FLAG))){
            return retMap;
        }

        //先判断文件是否存在

        File file = new File(filePath);
        if(!file.exists()){
            return retMap;
        }

        final CompilationUnit result = (CompilationUnit)getCompilationUnit(filePath);
        List importList = result.imports();
        for(Object obj : importList) {
            ImportDeclaration importDec = (ImportDeclaration)obj;
            importStrings.add(importDec.toString());
        }



        List types = result.types();
        TypeDeclaration typeDec = (TypeDeclaration) types.get(0);



        FieldDeclaration fieldDec[]=typeDec.getFields();

        for(FieldDeclaration field: fieldDec)
        {

            String fieldString = field.toString();
            //不是自动生成的代码，则需要保留
            if(fieldString.indexOf("@AutoCode")<0){

                fieldStrings.add(handleAnnotationNewLine(fieldString));
            }

        }



        MethodDeclaration methodDec[] = typeDec.getMethods();

        for(MethodDeclaration methodDesc:methodDec){

            String methodString = methodDesc.toString();
            if(methodString.indexOf("@AutoCode")<0){
                methodStrings.add(handleAnnotationNewLine(methodString));
            }
        }
        return retMap;

    }

    public static String handleAnnotationNewLine(String source){

        return source;
    }

    public static void main(String args[]){
//        ASTParser parser = ASTParser.newParser(AST.JLS3);
//        parser.setSource("public class A { int i = 9;  \n int j; \n ArrayList<Integer> al = new ArrayList<Integer>();j=1000; }".toCharArray());
//        //parser.setSource("/*abc*/".toCharArray());
//        parser.setKind(ASTParser.K_COMPILATION_UNIT);
//        //ASTNode node = parser.createAST(null);


//        final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
        final CompilationUnit result = (CompilationUnit)getCompilationUnit("F:\\data\\git\\repository\\mtcent-paas-new\\mtcent-paas\\paas-dao\\src\\main\\java\\com\\mtcent\\entity\\LiveApplication.java");

        List importList = result.imports();
        System.out.println("import:");
        for(Object obj : importList) {
            ImportDeclaration importDec = (ImportDeclaration)obj;


            System.out.println(importDec.toString());
        }


        List types = result.types();
        TypeDeclaration typeDec = (TypeDeclaration) types.get(0);
        System.out.println("className:"+typeDec.getName());

        FieldDeclaration fieldDec[]=typeDec.getFields();
        System.out.println("Fields:");
        for(FieldDeclaration field: fieldDec)
        {
            System.out.println("Field fragment:"+field.fragments());
            System.out.println("Field type:"+field.toString());
        }


        MethodDeclaration methodDec[] = typeDec.getMethods();
        System.out.println("Method:");
        for(MethodDeclaration methodDesc:methodDec){

            System.out.println(methodDesc.toString());
        }





//        cu.accept(new ASTVisitor() {
//
//            Set names = new HashSet();
//
//            public boolean visit(VariableDeclarationFragment node) {
//                SimpleName name = node.getName();
//                this.names.add(name.getIdentifier());
//                System.out.println("Declaration of '"+name+"' at line"+cu.getLineNumber(name.getStartPosition()));
//                return false; // do not continue to avoid usage info
//            }
//
//            public boolean visit(SimpleName node) {
//                if (this.names.contains(node.getIdentifier())) {
//                    System.out.println("Usage of '" + node + "' at line " +	cu.getLineNumber(node.getStartPosition()));
//                }
//                return true;
//            }
//
//        });
    }


    public static CompilationUnit getCompilationUnit(String path){
        try{
            BufferedInputStream bufferedInputStream = new BufferedInputStream(
                    new FileInputStream(path));
            byte[] input = new byte[bufferedInputStream.available()];

            bufferedInputStream.read(input);
            bufferedInputStream.close();
            String ret = new String(input);
            astParser.setKind(ASTParser.K_COMPILATION_UNIT);
            astParser.setSource(new String(input).toCharArray());
            astParser.setResolveBindings(true);
        /**/
            CompilationUnit result = (CompilationUnit) (astParser
                    .createAST(null)); // 很慢

            return result;
        }catch (Throwable t){
            throw new RuntimeException(t);
        }
    }
}
